using MultiAgentsClient.ChatDataStructures;
using MultiAgentsShared;
using static MultiAgentsClient.Manager.MessageManager;
using static MultiAgentsClient.Manager.ProjectManager;
using static MultiAgentsClient.Manager.UserInfoManager;

namespace MultiAgentsClient.Presentation;

public partial record HeaderPanelModel
{
    private readonly IEventBus eventBus;

    public IListState<string> LLMModels => ListState<string>.Empty(this);
    public IState<string> SelectedLLMModel => State.Value(this, () => "");
    public IState<bool> AllowToolCall => State.Value(this, () => false);
    public IState<string> ChatRoomName => State.Value(this, () => "");

    public HeaderPanelModel()
    {
        eventBus = EventBus.Instance;

        eventBus.Subscribe<FetchUserdataCompletedCommand>(async cmd => { await InitView(cmd); });
        eventBus.Subscribe<SwitchChatRoomCompleteCommand>(async cmd => { await SwitchChatRoomCompleteCommandHandler(cmd); });
        eventBus.Subscribe<AllowToolCallChangedCompleteCommand>(async cmd => { await AllowToolCallChangedCompleteCommandHandler(cmd); });
        eventBus.Subscribe<LLMModelSelectionChangedComleteCommand>(async cmd => { await LLMModelSelectionChangedComleteCommandHandler(cmd); });
    }

    public async ValueTask ChangeLlmModel(string llmModelName)
    {
        if (string.IsNullOrEmpty(llmModelName))
        {
            return;
        }

        await SelectedLLMModel.SetAsync(llmModelName);

        eventBus.Publish(new LLMModelSelectionChangedCommand(llmModelName));
    }

    private async ValueTask InitView(FetchUserdataCompletedCommand cmd)
    {
        UserDataModel userData = cmd.UserData;

        await LLMModels.RemoveAllAsync(match: item => true);

        await AllowToolCall.SetAsync(userData.allowToolCall);

        foreach (string model in userData.chatAccessibleLlmModels)
        {
            await LLMModels.AddAsync(model);
        }
    }

    private async ValueTask SwitchChatRoomCompleteCommandHandler(SwitchChatRoomCompleteCommand cmd)
    {
        await ChatRoomName.SetAsync(cmd.ChatRoomName);
    }

    private async ValueTask AllowToolCallChangedCompleteCommandHandler(AllowToolCallChangedCompleteCommand cmd)
    {
        await AllowToolCall.SetAsync(cmd.IsAllow);
    }

    private async ValueTask LLMModelSelectionChangedComleteCommandHandler(LLMModelSelectionChangedComleteCommand cmd)
    {
        IImmutableList<string> models = await LLMModels;
        if (models.Contains(cmd.Model))
        {
            await SelectedLLMModel.SetAsync(cmd.Model);
        }
        else
        {
            if (models.Count > 0)
            {
                await SelectedLLMModel.SetAsync(models[0]);
                eventBus.Publish(new LLMModelSelectionChangedCommand(models[0]));
            }
        }
    }
}
